#include "Tank.h"

CTank::CTank(float speed, float x, float y, int direction, hgeSprite** s1, hgeSprite** s2)
:CMoveObject(speed,direction), m_curState(0), m_TankSprite1(s1), m_TankSprite2(s2)
{
	SetRect(x,y,s1[0]->GetWidth(),s1[0]->GetHeight());
	SetCanDestory(true);
	m_CurrentTime = m_LastTime = 0.0f;
	m_LastX = x;
	m_LastY = y;
}

CTank::~CTank(void)
{
}

bool CTank::InitRole(float attspd, int maxlv, int group, int lv, long hp, int def, int ack)
{
	if(m_TankSprite1 == NULL || m_TankSprite2 == NULL)
		return false;

	m_RoleAttri.m_AttackSpeed = attspd;
	m_RoleAttri.m_RoleMaxLevel = maxlv;
	m_RoleAttri.m_RoleLevel = lv;
	m_RoleAttri.m_RoleHP = hp;
	m_RoleAttri.m_RoleDef = def;
	m_RoleAttri.m_RoleAck = ack;

	m_RoleGroup = group;
	if(group == GROUP_ENEMY)
		m_Type = TYPE_ENEMY;
	else
		m_Type = TYPE_PLAYER;

	return true;
}

bool CTank::OnMove(float timeDelta, int direction)
{
	m_LastX = GetX();
	m_LastY = GetY();
	float w = MOVEABLE_W - TANK_W;
	float h = MOVEABLE_H - TANK_H;
	bool rst = true;

	CMoveObject::OnMove(timeDelta, direction);

	if(GetX() < 0)
	{
		MoveRect(0,GetY());
		rst = false;
	}
	if(GetX() > w)
	{
		MoveRect(w,GetY());
		rst = false;
	}
	if(GetY() < 0)
	{
		MoveRect(GetX(),0);
		rst = false;
	}
	if(GetY() > h)
	{
		MoveRect(GetX(),h);
		rst = false;
	}

	if(!rst)
	{
		EnemyAfterImpact(timeDelta);
	}
	if(m_curState)
		m_curState = 0;
	else
		m_curState = 1;

	return rst;
}

void CTank::DoRender()
{
	if(m_curState)
		m_TankSprite2[m_Direction]->Render(GetX(),GetY());
	else
		m_TankSprite1[m_Direction]->Render(GetX(),GetY());

	for(std::list<CBullet*>::iterator it = m_Bullets.begin(); it != m_Bullets.end(); it++)
	{
		(*it)->DoRender();
	}
}

void CTank::DoAttack()
{
	float x = GetX();
	float y = GetY();
	switch(m_Direction)
	{
	case DIRECTION_UP:
		x = x + m_Width/2 - 4;
		break;
	case DIRECTION_RIGHT:
		x = x + m_Width;
		y = y + m_Height/2 - 4;
		break;
	case DIRECTION_DOWN:
		x = x + m_Width/2 - 4;
		y = y + m_Height;
		break;
	case DIRECTION_LEFT:
		y = y + m_Height/2 - 4;
		break;
	default:
		x = 0;
		y = 0;
		break;
	}

	CBullet *b = CBulletFactory::GetFactory()->CreateBullet(100.0f,m_Direction,x,y);
	if(b)
		m_Bullets.push_back(b);
}

void CTank::BulletMove(float timeDelta)
{
	for(std::list<CBullet*>::iterator it = m_Bullets.begin(); it != m_Bullets.end();)
	{
		(*it)->OnMove(timeDelta);
		std::list<CBullet*>::iterator tmp = it++;
		if(BulletOut(*tmp))
		{
			m_Bullets.erase(tmp);
		}
	}
}

bool CTank::IsHit(float x, float y, float w, float h)
{
	for(std::list<CBullet*>::iterator it = m_Bullets.begin(); it != m_Bullets.end();it++)
	{
		if((*it)->OnImpact(x,y,w,h))
		{
			m_Bullets.erase(it);
			return true;
		}
	}
	return false;
}

bool CTank::IsHit(CBaseObject* obj)
{
	if(obj->IsCanDestory())
	{
		for(std::list<CBullet*>::iterator it = m_Bullets.begin(); it != m_Bullets.end();it++)
		{
			if((*it)->OnImpact(obj->GetRect()))
			{
				m_Bullets.erase(it);
				return true;
			}
		}
	}

	return false;
}

bool CTank::BulletOut(CBullet* b)
{
	int d = b->GetDirection();
	switch(d)
	{
	case DIRECTION_UP:
	case DIRECTION_LEFT:
		return b->OnOutside(0,d);
	case DIRECTION_RIGHT:
		return b->OnOutside(WINDOW_WIDTH,d);
	case DIRECTION_DOWN:
		return b->OnOutside(WINDOW_HEIGHT,d);
	default:
		return false;
	}
}

void CTank::MovingCorrect(float dt, CBaseObject* obj)
{
	if(CMoveObject::OnImpact(obj->GetRect()))
	{
		if(obj->IsBlock())
		{
			MoveRect(m_LastX,m_LastY);
			EnemyAfterImpact(dt,obj);
		}
		else
		{
			SetTransparent();
		}
	}

}

void CTank::EnemyAfterImpact(float dt, CBaseObject* obj)
{
// 	m_CurrentTime += dt;
// 	float t = m_CurrentTime - m_LastTime;
	if(GetType() == TYPE_ENEMY)
	{
		m_LastTime = m_CurrentTime;
		if(obj && obj->IsCanDestory())
		{
			if(obj->GetType() ==TYPE_ENEMY)
			{
				CTank* enemy = (CTank*)obj;
				m_Direction = rand()%4;
				enemy->m_Direction = rand()%4;
			}
			else
				DoAttack();
		}
		else
			m_Direction = rand()%4;
	}
}

void CTank::SetTransparent()
{
// 	static HGE* hge = hgeCreate(HGE_VERSION);
// 	HTEXTURE hTex= (*m_TankSprite1)->GetTexture();
// 	DWORD dwColor = (*m_TankSprite1)->GetColor();
// 	int size = hge->Texture_GetWidth(hTex) * hge->Texture_GetHeight(hTex);
// 
// 	DWORD* dwTex = hge->Texture_Lock(hTex);
// 
// 	for(int i = 0; i < size; i++)
// 	{
// 			if((dwTex[i] & 0x00FFFFFF) == dwColor)
// 			{
// 					dwTex[i] &= 0x00FFFFFF;
// 			}
// 	}
// 	hge->Texture_Unlock(hTex);

}